#include "stdafx.h"


    namespace network
    {

        SBServerSession::SBServerSession(boost::asio::io_service& _ioService, SBSessionManager& _manager, boost::uint16_t _sessionId) :
        Session(_ioService),
        m_sessionManager(_manager),
        m_sessionId(_sessionId),
        m_sessionState(_not_logged_),
		m_stopRequesting( false )
        //inter_server_info_(NULL)

        {
        }

        SBServerSession::~SBServerSession()
        {
            //std::cout << "Destroying LoginSession" << std::endl;

            /*if ((m_sessionState == _inter_server_logged_) && (inter_server_info_ != NULL) )
            {
                std::cout << "Deconnexion char_serveur" << std::endl;
                login_server::get_instance()->delete_server(inter_server_info_);
                delete inter_server_info_;
            }*/

            /* BOOST_FOREACH( login_data::char_info *ci, m_charList)
             {
                 delete ci;
             }*/
        }

        void SBServerSession::start()
        {

            //std::cout << "New session" << std::endl;


            /*packet::WeaselKeyExchange shared_key(& (crypt.expendedKey()));
            first_packet_crypt().aes_crypt(shared_key);
            m_socket.async_write_some(shared_key,
                                      boost::bind(&SBServerSession::handle_write, shared_from_this(),
                                                  boost::asio::placeholders::error,
                                                  boost::asio::placeholders::bytes_transferred));

            first_packet_crypt().aes_decrypt(shared_key, 180);*/
            //buffer::hexDump(std::cout, *shared_key );

			//memset( &(*m_read_buffer), 0, 180 );
            // We listen for future reception
            /*boost::asio::async_read(	m_socket,boost::asio::buffer(*m_read_buffer), boost::asio::transfer_at_least(68),
                                                                    boost::bind(    &LoginSession::handle_read_first_packet,
                                                shared_from_this(),
                                                boost::asio::placeholders::error,
                                                boost::asio::placeholders::bytes_transferred));*/
			m_socket.async_read_some(	boost::asio::buffer( *m_read_buffer ),
							boost::bind(&SBServerSession::handle_read,
                            shared_from_this(),
                            boost::asio::placeholders::error,
                            boost::asio::placeholders::bytes_transferred));

        }

        void SBServerSession::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred)
        {

            if (!e)
            {

                /*if ( bytes_transferred < MIN_LOGIN_SESSION_PACKETS_SIZE || bytes_transferred > MAX_LOGIN_SESSION_PACKETS_SIZE )
                {
                    session_manager_.stop(shared_from_this());
                    return;
                }*/

                // Call to the parser to compute input data, it will do a callback toward the good function on_packet
                // No crypto wioth char-server
                //if ( m_sessionState != _inter_server_logged_ )
                    PacketManager::getSingleton().resolve(shared_from_this(), m_read_buffer, bytes_transferred); // Doit comporté une crypto
                //else
                //PacketManager::getSingleton().resolve(shared_from_this(), crypt.aes_decrypt(m_read_buffer, bytes_transferred), bytes_transferred);

                //m_read_buffer.reset();
                m_socket.async_read_some(boost::asio::buffer(*m_read_buffer),
                                         boost::bind(&SBServerSession::handle_read, shared_from_this(),
                                                     boost::asio::placeholders::error,
                                                     boost::asio::placeholders::bytes_transferred));

            }
            else if (e == boost::asio::error::operation_aborted)
            {
#if defined(_DEBUG) && defined(_OUTPUT)
				std::cout << "Error while reading socket stream : " << e.message() << std::endl;
#endif
                m_sessionManager.stop(shared_from_this());
            }



        }

        void SBServerSession::handle_read_first_packet(const boost::system::error_code& e, std::size_t bytes_transferred)
        {

            if (!e && !m_stopRequesting)
            {
                /* if ( bytes_transferred < MIN_LOGIN_SESSION_PACKETS_SIZE || bytes_transferred > MAX_LOGIN_SESSION_PACKETS_SIZE )
                 {
                 m_session_manager.stop(shared_from_this());
                        return;
                 }*/

                // Call to the parser to compute input data, it will do a callback toward the good function on_packet
                //PacketManager::getSingleton().resolve(shared_from_this(), first_packet_crypt().aes_decrypt(m_read_buffer, bytes_transferred), bytes_transferred); // Doit comporté une crypto
			
                //m_read_buffer.reset();

                m_socket.async_read_some(boost::asio::buffer(*m_read_buffer),
                                         boost::bind(&SBServerSession::handle_read, shared_from_this(),
                                                     boost::asio::placeholders::error,
                                                     boost::asio::placeholders::bytes_transferred));
            }
            else if (e != boost::asio::error::operation_aborted)
            {
                m_sessionManager.stop(shared_from_this());
            }
        }

        void SBServerSession::handle_write(const boost::system::error_code& e, std::size_t bytes_transferred)
        {

            if (!e)
            {
#if defined(_DEBUG) && defined(_OUTPUT)
                std::cout << "sb session writed ( size : " << bytes_transferred << " )" << std::endl;
#endif

				 m_socket.async_read_some(boost::asio::buffer(*m_read_buffer),
                                         boost::bind(&SBServerSession::handle_read, shared_from_this(),
                                                     boost::asio::placeholders::error,
                                                     boost::asio::placeholders::bytes_transferred));
		    }
            else if (e != boost::asio::error::operation_aborted)
            {
#if defined(_DEBUG) && defined(_OUTPUT)
                std::cout << e.message() << std::endl;
#endif
                m_sessionManager.stop(shared_from_this());

            }

        }

		void SBServerSession::on_packet(buffer::BasicBuffer& _packet)
        {

#if defined(_DEBUG) && defined(_OUTPUT)
            std::cout << " Raw data" << std::endl;
            std::cout << " Id = 0x0" << _packet.getId() << std::endl;
#endif
        }

		void SBServerSession::on_packet(packet::RequestGeneriks& _packet)
        {

#if defined(_DEBUG) && defined(_OUTPUT)
            std::cout << " Id = 0x0" << _packet.getId() << std::endl;
#endif
			try
			{
				Event::EventRequestGeneriks& packet = dynamic_cast< Event::EventRequestGeneriks& >( _packet );
				boost::shared_ptr< Event::EventRequestGeneriks > eventRequestGeneriks = boost::make_shared< Event::EventRequestGeneriks >( packet );
				POST_EVENT( eventRequestGeneriks );
			}catch( std::bad_cast& e )
			{
				std::cout << "Invalid packet casting : " << e.what() << std::endl;
			}
        }

        void SBServerSession::on_packet(packet::CancelOperation& _packet)
        {
#if defined(_DEBUG) && defined(_OUTPUT)
            std::cout << " handle reception packet Session: unspecialize packet!" << std::endl;
            std::cout << " Id = 0x0" << _packet.getId() << std::endl;
#endif
			m_stopRequesting = true;   
        }


    } // // namespace network
